/*
 * Title:        CloudScheduler Toolkit
 * Description:  a Toolkit for Modeling and Simulation of Job Scheduling and Resource Provisioning in Cloud System
 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
 * Author:       Fuhui Wu
 *
 * Copyright (c) 2013-2014, The National University of Defense Technology, China
 */

package org.nudt.jCloud.simulation;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.nudt.jCloud.infrastructure.Slot;
import org.nudt.jCloud.workload.Job;
import org.nudt.jCloud.workload.Task;

public class Request {
	private User user;
	private Job job;
	private List<Task> assignedTasks;
	private List<Task> unAssignedTasks;
	
	public Request(User user, Job job, List<Task> taskList){
		setUser(user);
		setJob(job);
		setAssignedTasks(new ArrayList<Task>());
		unAssignedTasks = new ArrayList<Task>();
		for(int i=0; i<taskList.size(); ++i){
			unAssignedTasks.add(taskList.get(i));
		}
	}
	
	public Task nextTask(Slot maxSlot){
		if(maxSlot.accommodate(getJob().getSlotType())){
			Task task = getUnAssignedTasks().get(0);
			getUnAssignedTasks().remove(task);
			getAssignedTasks().add(task);
			return task;
		}else{
			return null;
		}
	}
	
	public void assignTask(Task task) {
		getUnAssignedTasks().remove(task);
		getAssignedTasks().add(task);
	}
	
	public void cancelTaskAssign(Task task){
		getAssignedTasks().remove(task);
		getUnAssignedTasks().add(task);
		task.setSlot(null);
	}
		
	static class SortByArrivalTime implements Comparator<Request>{
		public int compare(Request request1, Request request2){
			if(request1.getJob().getXJob().getArrivalTime()>request2.getJob().getXJob().getArrivalTime()){
				return 1;
			}else if(request1.getJob().getXJob().getArrivalTime()<request2.getJob().getXJob().getArrivalTime()){
				return -1;
			}else{
				return 0;
			}
		}
		
	}
	
	static class SortBySizeInc implements Comparator<Request>{
		public int compare(Request request1, Request request2){
			if(request1.getUnAssignedTasks().size()>request2.getUnAssignedTasks().size()){
				return 1;
			}else if(request1.getUnAssignedTasks().size()<request2.getUnAssignedTasks().size()){
				return -1;
			}else{
				return 0;
			}
		}
	}
	
	static class SortBySizeDec implements Comparator<Request>{
		public int compare(Request request1, Request request2){
			if(request1.getUnAssignedTasks().size()<request2.getUnAssignedTasks().size()){
				return 1;
			}else if(request1.getUnAssignedTasks().size()>request2.getUnAssignedTasks().size()){
				return -1;
			}else{
				return 0;
			}
		}
	}
	
	static class SortByScheduledInc implements Comparator<Request>{
		public int compare(Request request1, Request request2){
			if(request1.getAssignedTasks().size()>request2.getAssignedTasks().size()){
				return 1;
			}else if(request1.getAssignedTasks().size()>request2.getAssignedTasks().size()){
				return -1;
			}else{
				return 0;
			}
		}
	}
	
	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}
	public List<Task> getAssignedTasks() {
		return assignedTasks;
	}
	public void setAssignedTasks(List<Task> assignedTasks) {
		this.assignedTasks = assignedTasks;
	}
	public List<Task> getUnAssignedTasks() {
		return unAssignedTasks;
	}
	public void setUnAssignedTasks(List<Task> unAssignedTasks) {
		this.unAssignedTasks = unAssignedTasks;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

}
